package com.cls.system.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.cls.common.entity.DictTree;
import com.cls.common.entity.MenuTree;
import com.cls.common.entity.QueryRequest;
import com.cls.common.utils.TreeUtil;
import com.cls.system.entity.Menu;
import com.cls.system.entity.SysDict;
import com.cls.system.mapper.SysDictMapper;
import com.cls.system.service.ISysDictService;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.annotation.Propagation;
import lombok.RequiredArgsConstructor;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageInfo;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.util.*;

/**
 * 字典表 Service实现
 *
 * @author slx
 * @date 2020-11-09 15:11:51
 */
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "dict")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements ISysDictService {

    private final SysDictMapper sysDictMapper;

    @Cacheable
    @Override
    public PageInfo<SysDict> findSysDicts(QueryRequest request, SysDict sysDict) {
        LambdaQueryWrapper<SysDict> queryWrapper = new LambdaQueryWrapper<>();
        // TODO 设置查询条件
        PageHelper.startPage(request.getPageNum(), request.getPageSize());
        List<SysDict> list = this.list(queryWrapper);
        PageInfo pageInfo = new PageInfo(list);
        return pageInfo;
    }
    @Cacheable(value = "dict", key = "'dict_pcode_'+T(String).valueOf(#code)", unless = "#result == null")
    @Override
    public List<Map<String, Object>> selectByParentCode(String code) {
        //根据code找id
        QueryWrapper<SysDict> queryWrapperParent = new QueryWrapper<>();

        queryWrapperParent.lambda().eq(SysDict::getCode,code);

        List<SysDict> listParent = this.baseMapper.selectList(queryWrapperParent);
        Long dictParentId=0L;
        if(listParent.size()>0){
            SysDict sysDictParent = listParent.get(0);
            dictParentId = sysDictParent.getDictId();
        }
        //根据父id找列表
        //第一级
        QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysDict::getPid,dictParentId);
        List<SysDict> list_type = this.baseMapper.selectList(queryWrapper);
        //第二级
        // 将封装的数据放在List<Map<String, Object>>的集合中
        List<Map<String,Object>> list = new ArrayList<>();
        for (SysDict type: list_type) {
            QueryWrapper<SysDict> queryWrapperChildrens = new QueryWrapper<>();
            queryWrapperChildrens.lambda().eq(SysDict::getPid,type.getDictId());
            List<SysDict> list_course = this.baseMapper.selectList(queryWrapperChildrens);
            Map<String,Object> map = new HashMap<>();
            map.put("type",type);
            map.put("course", list_course);
            list.add(map);
        }
        return list;
    }

    @Cacheable
    @Override
    public List<SysDict> findSysDicts(SysDict sysDict) {
        LambdaQueryWrapper<SysDict> queryWrapper = new LambdaQueryWrapper<>();
        // TODO 设置查询条件
        return this.baseMapper.selectList(queryWrapper);
    }

    @CacheEvict(allEntries = true)
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createSysDict(SysDict sysDict) {
        this.save(sysDict);
    }

    @CacheEvict(allEntries = true)
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSysDict(SysDict sysDict) {
        this.saveOrUpdate(sysDict);
    }

    @CacheEvict(allEntries = true)
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSysDict(SysDict sysDict) {
        LambdaQueryWrapper<SysDict> wrapper = new LambdaQueryWrapper<>();
        // TODO 设置删除条件
        this.remove(wrapper);
    }

    @CacheEvict(allEntries = true)
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSysDicts(String dictIds) {
        String[] dictIdsArray = dictIds.split(StringPool.COMMA);
        this.deleteList(Arrays.asList(dictIdsArray));

    }


    private void deleteList(List<String> dictIds) {
        List<String> list = new ArrayList<>(dictIds);
        dictIds.forEach(item ->
               baseMapper.deleteForId(Long.valueOf(item).longValue())
               // this.removeById(Long.valueOf(item).longValue())
        );
        LambdaQueryWrapper<SysDict> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SysDict::getPid, dictIds);
        List<SysDict> listDic = baseMapper.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(listDic)) {
            List<String> dictList = new ArrayList<>();
            listDic.forEach(dic -> dictList.add(String.valueOf(dic.getDictId())));
            list.addAll(dictList);
            this.deleteList(dictList);
        }
    }

    @Cacheable
    @Override
    public DictTree<SysDict> findDicts(SysDict sysDict) {
        QueryWrapper<SysDict> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(sysDict.getName())) {
            queryWrapper.lambda().like(SysDict::getName, sysDict.getName());
        }
        queryWrapper.lambda().orderByAsc(SysDict::getSort);
        List<SysDict> sysDicts = this.baseMapper.selectList(queryWrapper);
        List<DictTree<SysDict>> trees = this.convertDicts(sysDicts);

        return TreeUtil.buildDictTree(trees);
    }

    /**
     * 根据code查询字典
     *
     * @param code
     * @return
     */
    @Cacheable(value = "dict", key = "'dict_code_'+T(String).valueOf(#code)", unless = "#result == null")
    @Override
    public SysDict findByCode(String code) {
        SysDict sysDict = this.baseMapper.selectByCode(code);
        return sysDict;
    }

    /**
     * 根据多个code查询字典
     *
     * @param codes
     * @return
     */
    @Cacheable(value = "dict", key = "'dict_codes_'+T(String).valueOf(#codes)", unless = "#result == null")
    @Override
    public  List<SysDict>  findByCodes(List<String> codes) {
        List<SysDict> sysDict = this.baseMapper.selectByCodes(codes);
        return sysDict;
    }


    /**
     * 根据父级的code查询子集
     *
     * @param code
     * @return
     */
    @Cacheable(value = "dict", key = "'dict_parentcode_'+T(String).valueOf(#code)", unless = "#result == null")
    @Override
    public List<SysDict> findByParentCode(String code) {
        List<SysDict> list = this.baseMapper.findByParentCode(code);
        return list;
    }

    /**
     * 根据子级的code查询父集
     *
     * @param code
     * @return
     */
    @Cacheable(value = "dict", key = "'dict_forparentcode_'+T(String).valueOf(#code)", unless = "#result == null")
    @Override
    public SysDict selectForParentCode(String code) {
        SysDict list = this.baseMapper.findByChildrenCode(code);
        return list;
    }

    private List<DictTree<SysDict>> convertDicts(List<SysDict> menus) {
        List<DictTree<SysDict>> trees = new ArrayList<>();
        menus.forEach(menu -> {
            DictTree<SysDict> tree = new DictTree<>();
            tree.setId(String.valueOf(menu.getDictId()));
            tree.setParentId(String.valueOf(menu.getPid()));
            tree.setTitle(menu.getName());
            tree.setData(menu);
            trees.add(tree);
        });
        return trees;
    }

}
